package com.zhang.backend.common.exception;

import com.zhang.backend.common.response.Result;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Global exception handler for the application.
 * This class catches exceptions thrown by controllers and formats them into a standard Result object.
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * Handles generic runtime exceptions.
     *
     * @param e The exception caught.
     * @return A standardized failed Result.
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result<Object> handle(Exception e) {
        // Log the exception for debugging purposes
        e.printStackTrace();
        return Result.failed(e.getMessage());
    }

    /**
     * Handles validation exceptions (e.g., @Valid annotation failures).
     *
     * @param e The validation exception caught.
     * @return A standardized failed Result with validation error details.
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Result<Object>> handleValidationExceptions(MethodArgumentNotValidException e) {
        String errorMessage = e.getBindingResult().getFieldError().getDefaultMessage();
        return new ResponseEntity<>(Result.failed(errorMessage), HttpStatus.BAD_REQUEST);
    }

    /**
     * Handles custom application exceptions.
     *
     * @param e The custom API exception caught.
     * @return A standardized failed Result from the custom exception.
     */
    @ExceptionHandler(value = ApiException.class)
    @ResponseBody
    public Result<Object> handle(ApiException e) {
        if (e.getErrorCode() != null) {
            return Result.failed(e.getErrorCode());
        }
        return Result.failed(e.getMessage());
    }
}